package com.woniu.cq.ribbon;


import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.core.Balancer;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Daniel
 * @version 1.0.0
 * @ClassName WeightConfig
 * @Description 权重配置
 * @createTime 2020年09月17日 17:53:00
 */
@Configuration
public class WeightConfig extends AbstractLoadBalancerRule {
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object o) {
        //获取需要访问的服务名
        BaseLoadBalancer blb = (BaseLoadBalancer) this.getLoadBalancer();
        String name = blb.getName();
        //获取自身的clusterName
        String clusterName = nacosDiscoveryProperties.getClusterName();
        //获取nacos服务发现对象
        NamingService ns = nacosDiscoveryProperties.namingServiceInstance();
        try {
            //获取所有需要访问的服务节点
            List<Instance> allInstances = ns.getAllInstances(name);
            //过滤相同集群节点
            List<Instance> clusterInstance = allInstances.stream().filter(x -> {
                if (StringUtils.isNotEmpty(clusterName) && StringUtils.isNotEmpty(x.getClusterName())) {
                    if (clusterName.equals(x.getClusterName())) {
                        return true;
                    }
                }
                return false;
            }).collect(Collectors.toList());
            allInstances = clusterInstance != null && clusterInstance.size() > 0 ? clusterInstance : allInstances;
            //通过权重算法获取该服务的一个实例
            Instance instance = MyBalancer.getHostByRandomWeight(allInstances);
            return new NacosServer(instance);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @description: 内部类
     * @param: null
     * @return:
     */
    static class MyBalancer extends Balancer {
        public static Instance getHostByRandomWeight(List<Instance> host) {
            return Balancer.getHostByRandomWeight(host);
        }
    }
}
